package com.woniu.his.cms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.his.cms.common.CmsResultCode;
import com.woniu.his.cms.infra.model.NonDrug;
import com.woniu.his.cms.infra.mapper.NonDrugMapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.his.cms.infra.model.NonDrugItemRecord;
import com.woniu.his.cms.service.NonDrugItemRecordService;
import com.woniu.his.cms.service.NonDrugService;
import com.woniu.his.cms.service.dto.*;
import com.woniu.his.cms.service.param.DmsNonDrugSvParam;
import com.woniu.his.cms.service.param.NonDrugQuerySvParam;
import com.woniu.his.cms.service.param.NonDrugUpdateSvParam;
import com.woniu.his.cms.service.param.UploadCheckSvParam;
import com.woniu.his.dms.client.CaseHistoryClient;
import com.woniu.his.dms.client.param.CaseHistoryDetailResult;
import com.woniu.his.exception.HisException;
import com.woniu.his.result.Result;
import com.woniu.his.sms.client.SmsDeptQueryClient;
import com.woniu.his.sms.client.SmsStaffClient;
import com.woniu.his.sms.client.result.StaffAllResult;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 非药品项目表 服务实现类
 * </p>
 *
 * @author dx
 * @since 2022-11-28
 */
@Service
@Slf4j
public class NonDrugServiceImpl extends ServiceImpl<NonDrugMapper, NonDrug> implements NonDrugService {

    @Resource
    private SmsDeptQueryClient smsDeptQueryClient;

    @Resource
    private NonDrugItemRecordService nonDrugItemRecordService;

    @Resource
    private CaseHistoryClient caseHistoryClient;

    @Resource
    private SmsStaffClient smsStaffClient;


    //新建非药品
    @Override
    public CreateNonDrugDto create(DmsNonDrugSvParam dmsNonDrugSvParam) {
        ifCanCreateNonDrug(dmsNonDrugSvParam);
        NonDrug nonDrug = BeanUtil.copyProperties(dmsNonDrugSvParam, NonDrug.class);
        nonDrug.setCreateDate(new Date());
        nonDrug.setNonDrugStatus("ON");
        save(nonDrug);
        log.info("新增药品信息:{}", nonDrug);
        return BeanUtil.copyProperties(nonDrug, CreateNonDrugDto.class);
    }


    //根据ids删除非药品
    @Override
    public boolean delete(List<Long> ids) {
        for (Long id : ids) {
            if (getById(id).getNonDrugStatus().equals("OFF")) {
                throw new HisException(CmsResultCode.NON_DRUG_DELETED_WRONG);
            }
            //检查项目中不能有正在需要检查的
            List<NonDrugItemRecord> list = nonDrugItemRecordService.list(new QueryWrapper<NonDrugItemRecord>().eq("no_drug_id",
                    id).in("non_drug_item_status", "NOT_PAY", "PAID", "NOT_REGISTERED", "REGISTERED"));
            if (list.size() > 0) {
                throw new HisException(CmsResultCode.PATIENT_NEED_TO_CHECK);
            }
        }
        for (Long id : ids) {
            NonDrug nonDrug = getById(id);
            nonDrug.setNonDrugStatus("OFF");
            updateById(nonDrug);
        }
        return true;
    }

    //修改非药品
    @Override
    @GlobalTransactional
    public UpdateDrugDto updateNonDrug(NonDrugUpdateSvParam nonDrugUpdateSvParam) {
        Long id = nonDrugUpdateSvParam.getId();
        NonDrug nonDrug = getById(id);
        log.info("查到的nonDrug：{}", nonDrug);
        ifCanBeUpdated(nonDrugUpdateSvParam, nonDrug);
        NonDrug nonDrug1 = BeanUtil.copyProperties(nonDrugUpdateSvParam, NonDrug.class);
        log.info("更改后参数：{}", nonDrug1);
        //检查 ??
        saveOrUpdate(nonDrug1);
        return BeanUtil.copyProperties(getById(id), UpdateDrugDto.class);
    }

    //查询所有非药品
    @Override
    public List<DmsNonDrugDto> listAll() {
        List<NonDrug> list = list();
        List<DmsNonDrugDto> dmsNonDrugDtos = BeanUtil.copyToList(list, DmsNonDrugDto.class);
        for (DmsNonDrugDto dmsNonDrugDto : dmsNonDrugDtos) {
            String deptName = smsDeptQueryClient.findDeptById(getById(dmsNonDrugDto.getId()).getDeptId().intValue()).getData().getDeptName();
            dmsNonDrugDto.setDeptName(deptName);
        }
        return dmsNonDrugDtos;
    }


    //模糊查询非药品
    @Override
    public NonDrugQueryDto queryList(NonDrugQuerySvParam querySvParam) {

        NonDrugQueryDto nonDrugQueryDto = new NonDrugQueryDto();
        if (querySvParam.getPrice() != null && querySvParam.getPrice().compareTo(BigDecimal.ZERO) < 0) {
            throw new HisException(CmsResultCode.NON_DRUG_PRICE_LESS_THAN_ZERO);
        }
        QueryWrapper<NonDrug> wrapper = new QueryWrapper<>();
        creatNonDrugQueryMapper(querySvParam, wrapper);
        IPage<NonDrug> infoIPage = page(new Page<>(querySvParam.getPageNum(), querySvParam.getPageSize()), wrapper);

        log.info("查询后的参数：{}", infoIPage);
        if (infoIPage.getRecords().size() <= 0) {
            return null;
        }
        List<DmsNonDrugDto> list = infoIPage.getRecords().stream().map(o -> {
            DmsNonDrugDto dmsNonDrugDto = BeanUtil.copyProperties(o, DmsNonDrugDto.class);
            String deptName = smsDeptQueryClient.findDeptById(getById(dmsNonDrugDto.getId()).getDeptId().intValue()).getData().getDeptName();
            dmsNonDrugDto.setDeptName(deptName);
            return dmsNonDrugDto;
        }).collect(Collectors.toList());
        nonDrugQueryDto.setDmsNonDrugResults(list);
        nonDrugQueryDto.setIndexPage(infoIPage.getCurrent());
        nonDrugQueryDto.setTotal(infoIPage.getTotal());
        log.info("查询后的一共有几页：{}", infoIPage.getPages());
        return nonDrugQueryDto;
    }


    /**
     * 描述：根据科室id刷新患者待检查列表
     */
    @Override
    public List<DmsMechanicItemRecordDto> listByDept(Long deptId) {
        if (smsDeptQueryClient.findDeptById(deptId.intValue()).getData() == null) {
            throw new HisException(CmsResultCode.CAN_NOT_FIND_DEPT);
        }
        List<NonDrugItemRecord> nonDrugItemRecords = nonDrugItemRecordService.list(new QueryWrapper<NonDrugItemRecord>().
                eq("excute_dept_id", deptId).eq("non_drug_item_status", "REGISTERED").orderByAsc("log_date_time"));
        if (nonDrugItemRecords == null || nonDrugItemRecords.size() <= 0) {
            throw new HisException(CmsResultCode.NOBODY_NEED_TO_CHECK);
        }
        return nonDrugItemRecords.stream().map(o -> {
            DmsMechanicItemRecordDto recordDto = BeanUtil.copyProperties(o, DmsMechanicItemRecordDto.class);
            //设置项目名字
            recordDto.setNonDrugName(getById(o.getNoDrugId()).getNonDrugName());
            //查询病历表获得病人信息+医生姓名
            CaseHistoryDetailResult caseHistoryDetail = caseHistoryClient.selectEndCaseHistoryByReg(o.getCaseHistoryId()).getData();
            if (caseHistoryDetail == null) {
                throw new HisException(CmsResultCode.USE_EXCEPTION);
            }
            recordDto.setPatientName(caseHistoryDetail.getPatientName());
            recordDto.setPatientAgeStr(caseHistoryDetail.getAgeStr());
            recordDto.setPatientGender(caseHistoryDetail.getGender());
//            recordDto.setLogStaffName(caseHistoryDetail.getStaffName());  更新DMS依赖即可 ??
            return recordDto;
        }).collect(Collectors.toList());
    }


    /**
     * @Description: 医技登记
     * @Param:
     * @return:
     * @Date: 2022/11/29
     */
    @Override
    public boolean logNonDrugItem(Long itemRecordId, Long logStaffId) {
        List<StaffAllResult> data = smsStaffClient.QueryAll().getData();

        System.out.println(data.toString());

        NonDrugItemRecord itemRecord = checkStaffItemState(itemRecordId, logStaffId, data);
        //如果不是已缴费且未登记的状态
        if (!itemRecord.getNonDrugItemStatus().equals("NOT_REGISTERED")) {
            throw new HisException(CmsResultCode.NON_DRUG_ITEM_NOT_PAID);
        }
        for (StaffAllResult datum : data) {
            if (datum.getId().equals(logStaffId)) {
                itemRecord.setNonDrugItemStatus("REGISTERED");
                itemRecord.setLogStaffId(logStaffId);
                itemRecord.setLogDateTime(new Date());
                nonDrugItemRecordService.updateById(itemRecord);
                return true;
            }
        }
        return false;
    }


    /**
     * @Description: 上传结果
     * @Param:
     * @return:
     * @Date: 2022/11/29
     */
    @Override
    public boolean uploadResult(UploadCheckSvParam uploadCheckSvParam) {

        List<StaffAllResult> data = smsStaffClient.QueryAll().getData();
        NonDrugItemRecord itemRecord = checkStaffItemState(uploadCheckSvParam.getId(),
                uploadCheckSvParam.getExcuteStaffId(), data);
        if (!itemRecord.getNonDrugItemStatus().equals("REGISTERED")) {
            throw new HisException(CmsResultCode.NON_DRUG_ITEM_NOT_REGISTERED);
        }

        for (StaffAllResult datum : data) {
            if (datum.getId().equals(uploadCheckSvParam.getExcuteStaffId())) {
//                更新检查结果信息
                itemRecord.setNonDrugItemStatus("FINISH");
                itemRecord.setExcuteStaffId(datum.getId());
                itemRecord.setExcuteTime(new Date());
                itemRecord.setExcuteDeptId(datum.getDeptId());
                itemRecord.setEndDatetime(new Date());
                itemRecord.setCheckResult(uploadCheckSvParam.getCheckResult());
                itemRecord.setResultImgUrlList(uploadCheckSvParam.getResultImgUrlList());
                nonDrugItemRecordService.updateById(itemRecord);
                return true;
            }
        }
        return false;
    }

    private void creatNonDrugQueryMapper(NonDrugQuerySvParam querySvParam, QueryWrapper<NonDrug> wrapper) {
        wrapper.eq("non_drug_status", "ON");
        if (!querySvParam.getCode().trim().equals("") || !querySvParam.getCode().isEmpty())
            wrapper.like("non_drug_code", querySvParam.getCode());
        if (querySvParam.getDeptId() != null) wrapper.eq("dept_id", querySvParam.getDeptId());
        if (querySvParam.getPrice() != null) wrapper.like("price", querySvParam.getPrice());
        if (!querySvParam.getMnemonicCode().trim().equals("") || !querySvParam.getMnemonicCode().isEmpty())
            wrapper.like("mnemonic_code", querySvParam.getMnemonicCode());
        if (!querySvParam.getName().trim().equals("") || !querySvParam.getName().isEmpty())
            wrapper.like("non_drug_name", querySvParam.getName());
        if (!querySvParam.getRecordType().trim().equals("") || !querySvParam.getRecordType().isEmpty())
            wrapper.like("record_type", querySvParam.getRecordType());
    }

    private void ifCanBeUpdated(NonDrugUpdateSvParam nonDrugUpdateSvParam, NonDrug nonDrug) {
        if (nonDrug == null) {
            throw new HisException(CmsResultCode.NON_DRUG_NOT_EXITS);
        }
        if (nonDrug.getNonDrugStatus().equals("OFF")) {
            throw new HisException(CmsResultCode.NON_DRUG_DELETED_WRONG);
        }
        if (!(nonDrugUpdateSvParam.getRecordType().equals("CHECK") || nonDrugUpdateSvParam.getRecordType().equals("DISPOSITION") ||
                nonDrugUpdateSvParam.getRecordType().equals("TEST"))) {
            throw new HisException(CmsResultCode.NON_DRUG_TYPE_WRONG);
        }
        if (list(new QueryWrapper<NonDrug>().eq("non_drug_code", nonDrugUpdateSvParam.getNonDrugCode()).eq(
                "non_drug_status", "ON").ne("id", nonDrugUpdateSvParam.getId())).size() > 0) {
            throw new HisException(CmsResultCode.NON_DRUG_CODE_EXITS);
        }

        List<NonDrug> list = list(new QueryWrapper<NonDrug>().eq("non_drug_name", nonDrugUpdateSvParam.getNonDrugName()).eq(
                "non_drug_status", "ON").ne("id", nonDrugUpdateSvParam.getId()));
        System.out.println(list.toString());

        if (list(new QueryWrapper<NonDrug>().eq("non_drug_name", nonDrugUpdateSvParam.getNonDrugName()).eq(
                "non_drug_status", "ON").ne("id", nonDrugUpdateSvParam.getId())).size() > 0) {
            throw new HisException(CmsResultCode.NON_DRUG_NAME_EXITS);
        }
        if (list(new QueryWrapper<NonDrug>().eq("mnemonic_code", nonDrugUpdateSvParam.getMnemonicCode()).eq(
                "non_drug_status", "ON").ne("id", nonDrugUpdateSvParam.getId())).size() > 0) {
            throw new HisException(CmsResultCode.NON_DRUG_MEMORY_CODE_EXITS);
        }
    }

    private void ifCanCreateNonDrug(DmsNonDrugSvParam dmsNonDrugSvParam) {
        if (smsDeptQueryClient.findDeptById(dmsNonDrugSvParam.getDeptId().intValue()).getData() == null) {
            throw new HisException(CmsResultCode.ID_IS_WRONG);
        }
        if (!(dmsNonDrugSvParam.getRecordType().equals("CHECK") || dmsNonDrugSvParam.getRecordType().equals("DISPOSITION") ||
                dmsNonDrugSvParam.getRecordType().equals("TEST"))) {
            throw new HisException(CmsResultCode.NON_DRUG_TYPE_WRONG);
        }
        if (getOne(new QueryWrapper<NonDrug>().eq("non_drug_code", dmsNonDrugSvParam.getNonDrugCode()).eq(
                "non_drug_status", "ON")) != null) {
            throw new HisException(CmsResultCode.NON_DRUG_CODE_EXITS);
        }
        if (getOne(new QueryWrapper<NonDrug>().eq("non_drug_name", dmsNonDrugSvParam.getNonDrugName()).eq(
                "non_drug_status", "ON")) != null) {
            throw new HisException(CmsResultCode.NON_DRUG_NAME_EXITS);
        }
        if (getOne(new QueryWrapper<NonDrug>().eq("mnemonic_code", dmsNonDrugSvParam.getMnemonicCode()).eq(
                "non_drug_status", "ON")) != null) {
            throw new HisException(CmsResultCode.NON_DRUG_MEMORY_CODE_EXITS);
        }
    }

    private NonDrugItemRecord checkStaffItemState(Long itemRecordId, Long logStaffId, List<StaffAllResult> data) {
        if (data.size() <= 0) {
            throw new HisException(CmsResultCode.USE_EXCEPTION);
        }
        boolean b = false;
        for (StaffAllResult datum : data) {
            if (datum.getId().equals(logStaffId)) {
                b = true;
                break;
            }
        }
        if (!b) {
            throw new HisException(CmsResultCode.CAN_NOT_FIND_STAFF);
        }

        NonDrugItemRecord itemRecord = nonDrugItemRecordService.getById(itemRecordId);
        if (itemRecord == null) {
            throw new HisException(CmsResultCode.NON_DRUG_ITEM_NOT_EXITS);
        }
        return itemRecord;
    }
}
